package com.cskaoyan.javase.oop3._0abstract._0introduction;

/**
 * 抽象类的引入
 *
 * 以下猫狗继承案例，是一个非常基础的继承语法的代码。思考一下Animal类的继承体系，有什么问题吗？
 * 从以下两个角度分析：
 * 1. 从代码角度上，有没有冗余代码？
 * 2. 从设计角度上，在这个案例中，会存在一个`动物`对象吗？没有，不会创建Animal对象
 *      Animal在案例中,实际上是一个抽象的概念,就是被继承的
 *      在这种情况下,它不应该可以创建对象,而且它的行为,也不太能够被描述(只能知道它有这种行为)
 *
 * 所以说,综上,Animal这个类,我们有两个改进的需求:
 *      1.不要让它创建对象,它是一个顶层的概念,就是用来被继承,不是一个实际存在的实体
 *      2.shout方法应该没有方法体
 *
 *
 * 1.一个普通方法不可以没有方法体,除非它是抽象的,是一个抽象方法
 * 声明抽象方法的语法:
 * [访问权限修饰符] abstract 返回值类型 方法名(形参列表);
 *
 * 2.抽象方法必须在一个抽象类中,抽象类中有抽象方法,普通类没有抽象方法
 * 声明抽象类的语法:
 * [访问权限修饰符] abstract class 类名{
 *     // 类体
 * }
 *
 * @since 09:43
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 'Animal' is abstract; cannot be instantiated
        // new Animal();

        // 抽象类Animal仍然是一个父类,仍然具有多态现象
        Animal a;
        a = new Cat();
        a.shout();
        a = new Dog();
        a.shout();
    }
}
// Class 'Animal' must either be declared abstract or implement abstract method 'shout()' in 'Animal'
abstract class Animal {
    // Missing method body, or declare abstract
    // Abstract method in non-abstract class
    public abstract void shout();
}

class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("猫叫");
    }
}

class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("狗叫");
    }
}